package jkhttp

import (
	"crypto/tls"
	"errors"
	"io/ioutil"
	"jkgo/jk/jklog"
	"net/http"
	"strconv"
	"strings"
	"time"
)

type JKHttpQuery struct {
	url     string
	data    string
	Request *http.Request
	client  http.Client
}

func NewJKHttpQuery(url string, data string) (*JKHttpQuery, error) {
	h := &JKHttpQuery{
		url:  url,
		data: data,
	}
	var err error
	h.Request, err = http.NewRequest("POST", url, strings.NewReader(data))
	h.Request.Header.Set("Content-Type", "application/json")

	if err != nil {
		return nil, err
	}
	transport := &http.Transport{TLSClientConfig: &tls.Config{
		InsecureSkipVerify: true,
	}}
	h.client.Transport = transport
	return h, nil
}

func (h *JKHttpQuery) AddCookie(key, value string) {
	h.Request.AddCookie(&http.Cookie{
		Name:       key,
		Value:      value,
		Path:       "",
		Domain:     "",
		Expires:    time.Time{},
		RawExpires: "",
		MaxAge:     0,
		Secure:     false,
		HttpOnly:   false,
		SameSite:   0,
		Raw:        "",
		Unparsed:   nil,
	})
}

func (h *JKHttpQuery) Post() ([]byte, error) {
	resp, err := h.client.Do(h.Request)
	if err != nil {
		return nil, err
	}
	defer resp.Body.Close()
	body, err := ioutil.ReadAll(resp.Body)
	if err != nil {
		return nil, err
	}
	return body, nil
}

func JKGetDataSimple(url string, timeout int) ([]byte, error) {
	jklog.L().Debugln("post url: ", url)
	client := http.Client{
		Timeout: time.Duration(timeout) * time.Second,
	}
	resp, err := client.Get(url)
	if err != nil {
		jklog.L().Errorln("http post failed: ", err)
		return nil, err
	}
	defer resp.Body.Close()
	return ioutil.ReadAll(resp.Body)
}

func JKPostDataSimple(url string, args string, timeout int) ([]byte, error) {
	jklog.L().Debugln("post url: ", url)
	client := http.Client{
		Timeout: time.Duration(timeout) * time.Second,
	}
	resp, err := client.Post(url, "text/plain", strings.NewReader(args))
	if err != nil {
		jklog.L().Errorln("http post failed: ", err)
		return nil, err
	}
	defer resp.Body.Close()
	return ioutil.ReadAll(resp.Body)
}

func JKPostDataExtern(ip string, port int, page string, data []byte, timeout int) ([]byte, error) {
	url := "http://" + ip + ":" + strconv.Itoa(port) + "/" + page
	jklog.L().Debugln("post url: ", url)
	client := http.Client{
		Timeout: time.Duration(timeout) * time.Second,
	}
	resp, err := client.Post(url, "text/plain", strings.NewReader(string(data)))
	if err != nil {
		jklog.L().Errorln("http post failed: ", err)
		return nil, err
	}
	defer resp.Body.Close()
	return ioutil.ReadAll(resp.Body)
}

func JKPostData(iplist string, port int, page string, data []byte, timeout int) ([]byte, error) {
	ips := strings.Split(iplist, ",")
	for _, ipitem := range ips {
		data, err := JKPostDataExtern(ipitem, port, page, data, timeout)
		if err == nil {
			return data, nil
		}
	}
	return nil, errors.New("All post data failed")
}
